#include <iostream>
#include "myh/MyLog.hpp"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> //
#include <cstring>
#include "udpserve.hpp"
void HandleError(const std::string &funname, int _erron)
{
    if (_erron < 0)
    {
        lg(Error, "[%s-%d-%s]%s", __FILE__, __LINE__, funname, strerror(errno));
        exit(errno);
    }
}
void Explain()
{
    std::cout << "./client [ip] [port]" << std::endl;
}

void test1(uint16_t port)
{
    lg.ChangeFilePath(Screnn);
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    HandleError("socket", sockfd);
    lg(Debug, "[%s-%d-%s]%s", __FILE__, __LINE__, "socket", strerror(errno));

    struct sockaddr_in serveaddr;
    bzero(&serveaddr, sizeof(serveaddr));
    serveaddr.sin_family = AF_INET; // ipv4
    serveaddr.sin_port = htons(port);
    // inet_addr()	字符串→网络字节序	❌ 已过时
    // inet_aton()	字符串→网络字节序	✅ 可用
    // inet_ntoa()	网络字节序→字符串	❌ 不可重入
    // inet_pton()	字符串→网络字节序	✅ 推荐（支持IPv6）
    // inet_ntop()	网络字节序→字符串	✅ 推荐（支持IPv6）
    // INADDR_ANY (0.0.0.0)：监听所有网络接口
    // INADDR_LOOPBACK (127.0.0.1)：环回地址（本地测试）
    // INADDR_BROADCAST (255.255.255.255)：有限广播地址
    int ret1 = inet_pton(AF_INET, "0.0.0.0", &serveaddr.sin_addr);
    HandleError("inet_pton", ret1);
    lg(Debug, "[%s-%d-%s]%s", __FILE__, __LINE__, "inet_pton", strerror(errno));

    int ret2 = bind(sockfd, (const struct sockaddr *)&serveaddr, sizeof(serveaddr));
    HandleError("bind", ret2);
    lg(Debug, "[%s-%d-%s]%s", __FILE__, __LINE__, "bind", strerror(errno));

    struct sockaddr_in clientaddr;
    bzero(&clientaddr, sizeof(clientaddr));
    socklen_t len = sizeof(clientaddr);
    char buffer[1024];
    lg(Debug, "[%s-%d-%s]%s", __FILE__, __LINE__, "创建客户端结构体", strerror(errno));

    while (true)
    {
        std::cout << "收到的信息";
        std::cout.flush();
        // 信息交互
        size_t n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (sockaddr *)&clientaddr, &len);
        HandleError("recvfrom", n);
        buffer[n] = 0;
        std::cout << buffer << std::endl;
        // lg(Debug, "[%s-%d-%s]%s", __FILE__, __LINE__, "bind", buffer);
    }
}

void test2(uint16_t port)
{
    udpserve::Getinitance(port);
    udpserve::Getinitance(port)->run();
}

int main(int num, char *args[])
{
    if (num != 2)
    {
        Explain();
        exit(0);
    }
    uint16_t port = std::stol(args[1]);

    test2(port);

    return 0;
}